package com.yunbiao.ybbusstopplate.serialport.agreement;

import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;

import com.blankj.utilcode.util.FileIOUtils;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.ThreadUtils;
import com.blankj.utilcode.util.UiMessageUtils;
import com.yunbiao.ybbusstopplate.base.APP;
import com.yunbiao.ybbusstopplate.bean.SiteInfoBean;
import com.yunbiao.ybbusstopplate.utils.BytesUtils;
import com.yunbiao.ybbusstopplate.utils.StringUtils;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;

import tp.xmaihh.serialport.SerialHelper;
import tp.xmaihh.serialport.bean.ComBean;

public class TMPortAgreement extends BaseAgreement{
    private static final String TAG = "TMPortAgreement";

    private final File upSiteFile = new File(APP.Companion.getAppContext().getCacheDir(),"tmUpSiteFile.txt");
    private final File downSiteFile = new File(APP.Companion.getAppContext().getCacheDir(),"tmDownSiteFile.txt");
    private final File lineNameFile = new File(APP.Companion.getAppContext().getCacheDir(),"lineName.txt");
    private final File siteListVersionFile = new File(APP.Companion.getAppContext().getCacheDir(),"lineVersion.txt");

    private final LinkedHashMap<Integer,String> upSiteMap = new LinkedHashMap<>();
    private final LinkedHashMap<Integer,String> downSiteMap = new LinkedHashMap<>();

    private static final class Holder{
        public static final TMPortAgreement INSTANCE = new TMPortAgreement();
    }

    public static TMPortAgreement getInstance(){
        return Holder.INSTANCE;
    }

    private TMPortAgreement(){
        ThreadUtils.executeBySingle(new ThreadUtils.SimpleTask<Object>() {
            @Override
            public String[] doInBackground() throws Throwable {
                readUpSiteList();
                readDownSiteList();
                readLineName();
                readSiteListVersion();
                return new String[]{};
            }

            @Override
            public void onSuccess(Object obj) {

            }
        });
    }

    @Override
    public void setAgreementListener(IAgreementListener agreementListener) {
        d("setAgreementListener: 设置监听器");
        super.setAgreementListener(agreementListener);
    }

    public synchronized void anlzData(SerialHelper serialHelper,byte[] data){
        try {
            if (data == null || data.length <= 0) {
                d( "空日志");
                return;
            }

            //过滤无效指令
            String s = BytesUtils.bytesToHex(data);
            if(!s.startsWith("24242424")){
                d("未知指令");
                return;
            }

            //过滤长度不正确的指令
            byte length = data[6];
            String lengthHex = BytesUtils.byteToHex(length);
            int lengthInt = BytesUtils.hex16to10(lengthHex);
            if(data.length < lengthInt){
                d("指令长度不正确");
                return;
            }

            byte[] bytes = BytesUtils.SubByte(data, 0, lengthInt);

            String hex = BytesUtils.bytesToHex(bytes);
            d( "<-----" + hex);

            byte deviceAddress = bytes[4];
            byte order = bytes[5];
            byte direction = bytes[7];

//        d( "anlzData: " + BytesUtils.byteToHex(order));

            //节站屏线路信息查询
            if(deviceAddress == 0x17 && order == 0x19){
                d("anlzData: 节站屏线路信息查询");
                queryLineInfo(serialHelper,bytes);
            }
            //节站屏线路同步包
//        else if(deviceAddress == 0x16 && order == 0x20){
//            d("anlzData: 节站屏线路同步包");
//            syncLine(bytes);
//        }
            //线路站点下载
            else if(deviceAddress == 0x16 && order == 0x17){
                d("anlzData: 线路站点下载");
                downloadLine(bytes);
            }
            //进出站播报
            else if(order == 0x11){
                d("anlzData: 进出站播报");
                inOutSite(bytes);
            }
            else if(order == 0x21){
                correctTime(bytes);
            }
        } catch (Exception e){
            LogUtils.e(e);
//            if (agreementListener != null) {
//                agreementListener.agreementFailed();
//            }
        }
    }

    private void correctTime(byte[] bytes){
        // 242424241621103816071001161cbbcb
        byte[] bytes1 = BytesUtils.SubByte(bytes, 8, 6);
        int[] intArray = new int[bytes1.length];
        for (int i = 0; i < intArray.length; i++) {
            intArray[i] = BytesUtils.hex16to10(BytesUtils.byteToHex(bytes1[i]));
        }
        intArray[0] = Integer.parseInt("20" + intArray[0]);
        Log.d(TAG, "correctTime: " + Arrays.toString(intArray));
        UiMessageUtils.getInstance().send(777,intArray);
    }

    //车机查询屏幕线路版本
    private void queryLineInfo(SerialHelper serialHelper,byte[] bytes){
        String head,addr,order,length,flag,status,line,version,auth;

        head = "24242424";

        addr = "17";

        order = "19";

        //组装包标识
        byte PACKAGE_FLAG = bytes[7];
        flag = BytesUtils.byteToHex(PACKAGE_FLAG);
        d("queryLineInfo: 包标识：" + flag);

        status = "0000";
        d("queryLineInfo: 自检状态：" + status);

        //组装线路名称长度和线路名
        String line_name = readLineName();
        if(!TextUtils.isEmpty(line_name)){
            try {
                d( "queryLineInfo: 线路名称：" + line_name);
                byte[] LINE_NAME = line_name.getBytes("GB2312");
                String lineNameHex = BytesUtils.bytesToHex(LINE_NAME);
                d( "queryLineInfo: 线路名称HEX：" + lineNameHex);

                int lineNameLength = BytesUtils.hexToByteArray(lineNameHex).length;
                d( "queryLineInfo: 线路名称长度：" + lineNameLength);

                String lineNameLengthHex = Integer.toHexString(lineNameLength);
                lineNameLengthHex = lineNameLengthHex.length() == 1 ? "0" + lineNameLengthHex : lineNameLengthHex;
                d( "queryLineInfo: 线路名称长度Hex：" + lineNameLengthHex);

                line = lineNameLengthHex + lineNameHex;
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                line = "0100";
            }
        } else {
            line = "0100";
        }
        d("queryLineInfo: 线路名称：" + line);

        version = readSiteListVersion();
        if(TextUtils.isEmpty(version)){
            version = "00";
        }
        d( "queryLineInfo: 线路版本：" + version);

        //组装数据长度
        String lengthHex = Integer.toHexString(BytesUtils.hexToByteArray(head + addr + order + flag + status + line + version).length + 3);
        length = lengthHex.length() == 1 ? "0" + lengthHex : lengthHex;

        String unAuthHex = head + addr + order + length + flag + status + line + version;
        d( "queryLineInfo: 校验前：" + unAuthHex);

        //组装校验位
        byte[] unAuthBytes = BytesUtils.hexToByteArray(unAuthHex);
        byte[] authValueBytes = getCRCBytes(unAuthBytes);
        auth = BytesUtils.bytesToHex(authValueBytes);
        d("校验位222：" + auth);

        String HEX = head + addr + order + length + flag + status + line + version + auth;
        d( "queryLineInfo: 最终数据：" + HEX);
        if(serialHelper != null){
            serialHelper.sendHex(HEX);
        }
    }

    // 24 24 24 24
    // 17
    // 19
    // 11
    // 08
    // 00 00
    // 03
    // 42 31 32
    // 04
    // 6A98

    // 24 24 24 24 //包头
    // 17 //地址
    // 19 //命令
    // 0F //长度
    // 11 //包标识
    // 00 00 //自检状态
    // 01 //名称长度
    // 01 //名称数据
    // 02 //名称版本
    // F8 9D //校验位

    /**
     * 24 24 24 24 //包头 [0,1,2,3]
     * 16 //设备地址 [4]
     * 17 //命令 [5]
     * 20 //长度 [6]
     * 04 //站名列表版本 [7]
     * 03 //线路名称长度 [8]
     * 42 31 32 //线路名称内容 [9,10,11]
     * 00 //0上行1下行 [12]
     * 21 //站点总数 [13]
     * 01 //站点编号 [14]
     * 0e //站点名称长度 [15]
     * bf c6 d1 a7 b4 f3 b5 c0 ce f7 cb c4 bb b7 //站点名称 [16 - 29]
     * 8f 75 //校验 [30,31]
     */
    private void downloadLine(byte[] bytes){
        int index = 0;

        index = 5;//命令
        byte ORDER = bytes[index];

        index = 7;//站点名列表版本
        byte STATION_LIST_VERSION = bytes[index];
        String stationListVersion = BytesUtils.byteToHex(STATION_LIST_VERSION);
//        d( "站点列表版本：" + stationListVersion);

        index = 8;//线路名长度
        byte LINE_NAME_LENGTH = bytes[index];
        int lineNameLength = BytesUtils.hex16to10(BytesUtils.byteToHex(LINE_NAME_LENGTH));
//        d( "线路名称长度：" + lineNameLength);

        index = 9;//线路名称内容
        byte[] LINE_NAME = BytesUtils.SubByte(bytes, index, lineNameLength);
        String lineNameHex = BytesUtils.bytesToHex(LINE_NAME);
        String lineName = StringUtils.hexStringToString(lineNameHex, "GB2312");
//        d( "线路名称HEX：" + lineNameHex);
//        d( "线路名称：" + lineName);

        index += lineNameLength;//方向 [12]
        byte DIRECTION = bytes[index];
//        d( DIRECTION == 0x00 ? "上行" : "下行");

        index ++;//站点总数
        byte STATION_NUMBER = bytes[index];
        int stationNumber = BytesUtils.hex16to10(BytesUtils.byteToHex(STATION_NUMBER));
//        d( "站点总数：" + stationNumber);

        index ++;//站点编号
        byte STATION_INDEX = bytes[index];
        int stationIndex = BytesUtils.hex16to10(BytesUtils.byteToHex(STATION_INDEX));
//        d( "站点编号：" + stationIndex);

        index ++;//站点名称长度
        byte STATION_NAME_LENGTH = bytes[index];
        int stationNameLength = BytesUtils.hex16to10(BytesUtils.byteToHex(STATION_NAME_LENGTH));
//        d( "站点名称长度：" + stationNameLength);

        index ++;//站点内容
        byte[] STATION_NAME = BytesUtils.SubByte(bytes, index, stationNameLength);
        String stationNameHex = BytesUtils.bytesToHex(STATION_NAME);
        String stationName = StringUtils.hexStringToString(stationNameHex);
//        d( "站点名称HEX：" + stationNameHex);
//        d( "站点名称：" + stationName);

        if (DIRECTION == 0x00) {
            if(stationIndex == 1){
                mSiteListChanged = true;
                d( "收到数据更新");
                if(!upSiteMap.isEmpty()){
                    d( "清除上行数据");
                    upSiteMap.clear();
                }
            }

            if(upSiteMap.containsKey(stationIndex)){
                String s = upSiteMap.get(stationIndex);
                if(TextUtils.equals(stationName,s)){
                    return;
                }
            }

            upSiteMap.put(stationIndex,stationName);
            d( "上行站点：" + stationNumber + " --- " + stationIndex + " --- " + stationName);

            if(stationIndex == stationNumber){
                d( "上行线路同步完毕------------------------");
                saveLineName(lineName);
                saveLineVersion(stationListVersion);
                saveUpList(upSiteMap.values());

                if(agreementListener != null){
                    d( "发送站点列表");
                    ArrayList<String> siteList = new ArrayList<>(upSiteMap.values());
                    agreementListener.onSiteListResult(siteList);
                    agreementListener.onLineInfoResult(new String[]{lineName,siteList.get(0),siteList.get(siteList.size() - 1)});
                }
            }
        } else if(DIRECTION == 0x01){
            if(stationIndex == 1 && downSiteMap.size() > 1){
                downSiteMap.clear();
                d( "清除下行数据");
            }

            if(downSiteMap.containsKey(stationIndex)){
                String s = downSiteMap.get(stationIndex);
                if(TextUtils.equals(stationName,s)){
                    return;
                }
            }

            downSiteMap.put(stationIndex,stationName);
            d( "下行站点：" + stationNumber + " --- " + stationIndex + " --- " + stationName);
            saveDownList(downSiteMap.values());

//            if(stationIndex == stationNumber){
//                d( "下行线路同步完毕------------------------");
//                saveDownList(downSiteMap.values());
//            }
        }
    }

    /***
     * 24 24 24 24 包头
     * 16 地址
     * 20 命令
     * 24 长度
     * 0C 标识
     * 04 列表版本
     * 03 线路名称长度
     * 42 31 32 //线路名称内容
     * 06 首站
     * BB F0 B3 B5 D5 BE 首战
     * 0C 末站
     * D6 A3 B4 F3 D0 C2 C7 F8 C4 CF C3 C5 末站
     * 00
     * 94 4A
     */
    //标识站点信息是否改变，以及限制线路信息同步里的回调次数，在上行站点开始同步的时候置为true，在回调之后置为false
    private boolean mSiteListChanged = false;
    //缓存上下行标识，默认为上行
    private byte mUpDownFlag = 0x11;
    /**
     * 24 24 24 24 //包头 [0,1,2,3]
     * 7f //设备地址 [4]
     * 11 //命令 [5]
     * 11 //长度 [6]
     * 00 //方向 [7]
     * 01 //进出站类型 [8]
     * 30 42 31 32 //线路代码 [0,10,11,12]
     * 21 //站点总数 [13]
     * 03 //当前站号 [14]
     * 91 23 [15,16]
     */
    private void inOutSite(byte[] bytes){
        byte UP_DOWN_FLAG = bytes[7];
        //如果上下行标识不等于
        Log.d(TAG, "inOutSite: " + (mUpDownFlag != UP_DOWN_FLAG) + " --- " + mSiteListChanged);
        if(mUpDownFlag != UP_DOWN_FLAG || mSiteListChanged){
            mUpDownFlag = UP_DOWN_FLAG;
            mSiteListChanged = false;

            ArrayList<String> siteList = new ArrayList<>();
            switch (mUpDownFlag) {
                case 0x00://进站
                    d( "发送上行站点列表");
                    siteList.addAll(upSiteMap.values());
                    break;
                case 0x01://出站
                    d( "发送下行站点列表");
                    if(downSiteMap.isEmpty()){
                        List<String> upList = new ArrayList<>(upSiteMap.values());
                        Collections.reverse(upList);
                        for (int i = 0; i < upList.size(); i++) {
                            downSiteMap.put(i + 1,upList.get(i));
                        }
                        d("下行数据为空，反转上行数据：" + downSiteMap.values());
                    }
                    siteList.addAll(downSiteMap.values());
                    break;
            }

            if(!siteList.isEmpty()){
                agreementListener.onSiteListResult(siteList);
                String lineName = readLineName();
                agreementListener.onLineInfoResult(new String[]{lineName,siteList.get(0),siteList.get(siteList.size() - 1)});
            }
       }

        byte IN_OUT = bytes[8];//进出站标识

        byte STATION_INDEX = bytes[14];//站点序号
        int stationIndex = BytesUtils.hex16to10(BytesUtils.byteToHex(STATION_INDEX));
        d( (IN_OUT == 0x00 ? "进站：" : "出战：") + stationIndex);

        SiteInfoBean siteInfoBean = new SiteInfoBean();
        siteInfoBean.setSiteName(""/*siteName*/);
        siteInfoBean.setStutas(IN_OUT == 0x00 ? 1 : 0);
        siteInfoBean.setIndex(IN_OUT == 0x00 ? stationIndex - 1 : stationIndex);

        if(agreementListener != null){
            agreementListener.onSiteTipResult(siteInfoBean);
        }
    }

    //保存上行站点
    private void readUpSiteList(){
        upSiteMap.clear();
        d("上行数据路径：" + upSiteFile.getPath());
        String upSiteString = FileIOUtils.readFile2String(upSiteFile);
        d( "读取上行数据缓存：" + upSiteString);
        if(!TextUtils.isEmpty(upSiteString)){
            String[] split = upSiteString.split(",");
            for (int i = 0; i < split.length; i++) {
                String s = split[i];
                if(!TextUtils.isEmpty(s)){
                    upSiteMap.put(i + 1,s);
                }
            }
        }
    }

    //读取下行站点
    private void readDownSiteList(){
        downSiteMap.clear();
        d("下行数据路径：" + downSiteFile.getPath());
        String upSiteString = FileIOUtils.readFile2String(downSiteFile);
        d( "读取下行数据缓存：" + upSiteString);
        if(!TextUtils.isEmpty(upSiteString)){
            String[] split = upSiteString.split(",");
            for (int i = 0; i < split.length; i++) {
                String s = split[i];
                if(!TextUtils.isEmpty(s)){
                    downSiteMap.put(i + 1,s);
                }
            }
        }

        if(downSiteMap.isEmpty()){
            List<String> upList = new ArrayList<>(upSiteMap.values());
            Collections.reverse(upList);
            for (int i = 0; i < upList.size(); i++) {
                downSiteMap.put(i + 1,upList.get(i));
            }
            d("下行数据为空，反转上行数据：" + downSiteMap.values());
        }
    }

    //读取线路名称
    private String readLineName(){
        String readFile2String = FileIOUtils.readFile2String(lineNameFile);
        d( "读取线路名称缓存：" + readFile2String);
        return readFile2String;
    }

    private String readSiteListVersion(){
        String readFile2String = FileIOUtils.readFile2String(siteListVersionFile);
        d( "读取站点列表版本缓存：" + readFile2String);
        return readFile2String;
    }

    //保存线路名称
    private void saveLineName(String lineName){
        boolean b = FileIOUtils.writeFileFromString(lineNameFile, lineName, false);
        d( "导出站点名称：" + b);
    }

    //保存线路版本
    private void saveLineVersion(String siteListVersion){
        boolean b1 = FileIOUtils.writeFileFromString(siteListVersionFile, siteListVersion,false);
        d( "导出站点版本：" + b1);
    }

    //保存上行站点
    private void saveUpList(Collection<String> collection){
        StringBuilder stringBuilder = new StringBuilder();
        for (String s : collection) {
            stringBuilder.append(s).append(",");
        }
        boolean b = FileIOUtils.writeFileFromString(upSiteFile, stringBuilder.toString(), false);
        d( "导出上行站点：" + b);
    }

    //保存下行站点
    private void saveDownList(Collection<String> collection){
        StringBuilder stringBuilder = new StringBuilder();
        for (String s : collection) {
            stringBuilder.append(s).append(",");
        }
        boolean b = FileIOUtils.writeFileFromString(downSiteFile, stringBuilder.toString(), false);
        d( "导出下行站点：" + b);
    }

    private void d(String log){
//        Log.d(TAG, log);
        LogUtils.d(TAG,log);
    }
    /***
     * 24 24 24 24 包头
     * 16 地址
     * 20 命令
     * 26 长度
     * 0C 标识
     * 04 列表版本
     * 03 线路名称长度
     * 42 31 32 //线路名称内容
     * 0E
     * BF C6 D1 A7 B4 F3 B5 C0 CE F7 CB C4 BB B7
     * 06
     * BB F0 B3 B5 D5 BE
     * 00
     * E0 7B
     * @param bytes
     */
//    private void syncLine(byte[] bytes){
//        if(!mSiteListChanged){
//            return;
//        }
//        mSiteListChanged = false;
//
//        int index;
//
//        index = 8;//站名列表版本
//        byte SITE_LIST_VERSION = bytes[index];
//        String siteListVersion = BytesUtils.byteToHex(SITE_LIST_VERSION);
//
//        index = 9;//线路名称长度
//        byte LINE_NAME_LENGTH = bytes[index];
//        int lineNameLength = BytesUtils.hex16to10(BytesUtils.byteToHex(LINE_NAME_LENGTH));
//
//        index = 10;
//        byte[] LINE_NAME = BytesUtils.SubByte(bytes, index, lineNameLength);
//        String lineName = StringUtils.hexStringToString(BytesUtils.bytesToHex(LINE_NAME));
//
//        this.mLineName = lineName;
//        saveLineName(this.mLineName);
//        saveLineVersion(siteListVersion);
//        saveUpList(upSiteMap.values());
//        saveDownList(downSiteMap.values());
//
//        d("线路同步：" + siteListVersion + "," + lineName);
//        d("监听器：" + agreementListener);
//        if(agreementListener != null){
//            d( "发送站点列表");
//            ArrayList<String> siteList = new ArrayList<>(upSiteMap.values());
//            agreementListener.onSiteListResult(siteList);
//            agreementListener.onLineInfoResult(new String[]{lineName,siteList.get(0),siteList.get(siteList.size() - 1)});
//        }
//    }


    private static final int[] CRC16table = {
            0x0000,0xC0C1,0xC181,0x0140,0xC301,0x03C0,0x0280,0xC241,
                0xC601,0x06C0,0x0780,0xC741,0x0500,0xC5C1,0xC481,0x0440,
                0xCC01,0x0CC0,0x0D80,0xCD41,0x0F00,0xCFC1,0xCE81,0x0E40,
                0x0A00,0xCAC1,0xCB81,0x0B40,0xC901,0x09C0,0x0880,0xC841,
                0xD801,0x18C0,0x1980,0xD941,0x1B00,0xDBC1,0xDA81,0x1A40,
                0x1E00,0xDEC1,0xDF81,0x1F40,0xDD01,0x1DC0,0x1C80,0xDC41,
                0x1400,0xD4C1,0xD581,0x1540,0xD701,0x17C0,0x1680,0xD641,
                0xD201,0x12C0,0x1380,0xD341,0x1100,0xD1C1,0xD081,0x1040,
                0xF001,0x30C0,0x3180,0xF141,0x3300,0xF3C1,0xF281,0x3240,
                0x3600,0xF6C1,0xF781,0x3740,0xF501,0x35C0,0x3480,0xF441,
                0x3C00,0xFCC1,0xFD81,0x3D40,0xFF01,0x3FC0,0x3E80,0xFE41,
                0xFA01,0x3AC0,0x3B80,0xFB41,0x3900,0xF9C1,0xF881,0x3840,
                0x2800,0xE8C1,0xE981,0x2940,0xEB01,0x2BC0,0x2A80,0xEA41,
                0xEE01,0x2EC0,0x2F80,0xEF41,0x2D00,0xEDC1,0xEC81,0x2C40,
                0xE401,0x24C0,0x2580,0xE541,0x2700,0xE7C1,0xE681,0x2640,
                0x2200,0xE2C1,0xE381,0x2340,0xE101,0x21C0,0x2080,0xE041,
                0xA001,0x60C0,0x6180,0xA141,0x6300,0xA3C1,0xA281,0x6240,
                0x6600,0xA6C1,0xA781,0x6740,0xA501,0x65C0,0x6480,0xA441,
                0x6C00,0xACC1,0xAD81,0x6D40,0xAF01,0x6FC0,0x6E80,0xAE41,
                0xAA01,0x6AC0,0x6B80,0xAB41,0x6900,0xA9C1,0xA881,0x6840,
                0x7800,0xB8C1,0xB981,0x7940,0xBB01,0x7BC0,0x7A80,0xBA41,
                0xBE01,0x7EC0,0x7F80,0xBF41,0x7D00,0xBDC1,0xBC81,0x7C40,
                0xB401,0x74C0,0x7580,0xB541,0x7700,0xB7C1,0xB681,0x7640,
                0x7200,0xB2C1,0xB381,0x7340,0xB101,0x71C0,0x7080,0xB041,
                0x5000,0x90C1,0x9181,0x5140,0x9301,0x53C0,0x5280,0x9241,
                0x9601,0x56C0,0x5780,0x9741,0x5500,0x95C1,0x9481,0x5440,
                0x9C01,0x5CC0,0x5D80,0x9D41,0x5F00,0x9FC1,0x9E81,0x5E40,
                0x5A00,0x9AC1,0x9B81,0x5B40,0x9901,0x59C0,0x5880,0x9841,
                0x8801,0x48C0,0x4980,0x8941,0x4B00,0x8BC1,0x8A81,0x4A40,
                0x4E00,0x8EC1,0x8F81,0x4F40,0x8D01,0x4DC0,0x4C80,0x8C41,
                0x4400,0x84C1,0x8581,0x4540,0x8701,0x47C0,0x4680,0x8641,
                0x8201,0x42C0,0x4380,0x8341,0x4100,0x81C1,0x8081,0x4040
    };

    private static byte[] getCRCBytes(byte[] data){
        int crc = 0x0000;
        for (byte b : data) {
            crc = (crc >>> 8) ^ CRC16table[(crc ^ b) & 0xff];
        }
        return new byte[]{(byte) (0xff & crc), (byte) ((0xff00 & crc) >> 8)};
    }

    /*int CRC16_isr(char[] Dat,int len){
        int i,TxCRC16 = 0;
        for (i = 0; i < len; i++) {
            TxCRC16 = (CRC16table[Dat[i]^(TxCRC16&0xFF)]^(TxCRC16/0x100));
        }
        if(TxCRC16 == 0x0000){
            TxCRC16 = 0xFFFF;
        }
        return TxCRC16;
    }*/

    /*public static String getCRC16(String source) {
        int crc = 0xA1EC; 		 	 // 初始值
        int polynomial = 0x1021;	         // 校验公式 0001 0000 0010 0001
        byte[] bytes = BytesUtils.hexToByteArray(source);

        for (byte b : bytes) {
            for (int i = 0; i < 8; i++) {
                boolean bit = ((b >> (7 - i) & 1) == 1);
                boolean c15 = ((crc >> 15 & 1) == 1);
                crc <<= 1;
                if (c15 ^ bit)
                    crc ^= polynomial;
            }
        }
        crc &= 0xffff;
        StringBuffer result = new StringBuffer(Integer.toHexString(crc));
        while (result.length() < 4) {		 //CRC检验一般为4位，不足4位补0
            result.insert(0, "0");
        }
        return result.toString();
    }*/







    //    List<String> testList = new ArrayList<>();
    public void test(){
//        testList.clear();

//        File file = new File(Environment.getExternalStorageDirectory(),"TMDATA.txt");
//        List<String> strings = FileIOUtils.readFile2List(file);
//        for (String string : strings) {
//            String newString = string.replaceAll("节站屏站名列表下载 :","").replaceAll(" ","");
//            if(TextUtils.isEmpty(newString)){
//                continue;
//            }
//            testList.add(newString);
//        }
//
//        ThreadUtils.executeBySingle(new ThreadUtils.SimpleTask<Object>() {
//            @Override
//            public Object doInBackground() throws Throwable {
//                for (String s : testList) {
//                    byte[] bytes = BytesUtils.hexToByteArray(s);
//
//                    anlzData(null,bytes);
//
//                    Thread.sleep(100);
//                }
//                d( "doInBackground:-----------------------");
//                return new Object();
//            }
//
//            @Override
//            public void onSuccess(Object o) {
//
//            }
//        });

        new Thread(new Runnable() {
            @Override
            public void run() {
                List<byte[]> orderList = new ArrayList<>();
                List<byte[]> respList = new ArrayList<>();

                List<String> stringList = FileIOUtils.readFile2List(new File(Environment.getExternalStorageDirectory(),"TMTMSite.txt"));
                if(!stringList.isEmpty()){
                    for (String s : stringList) {
                        if(TextUtils.isEmpty(s)){
                            continue;
                        }
                        if(s.contains("<-----")){
                            continue;
                        }
                        if(s.contains("--->")){
                            int i = s.lastIndexOf(">");
                            String substring = s.substring(i + 1);
                            byte[] bytes = BytesUtils.hexToByteArray(substring);
                            if(bytes.length < 6 || bytes[6] != 0x11){
                                continue;
                            }
                            respList.add(bytes);
                        }
                        if(s.contains("<---")){
                            int i = s.lastIndexOf("-");
                            String substring = s.substring(i + 1);

                            byte[] bytes = BytesUtils.hexToByteArray(substring);
                            if(bytes.length < 6){
                                continue;
                            }

                            byte deviceAddress = bytes[4];
                            byte order = bytes[5];
                            if(deviceAddress != 0x17 && deviceAddress != 0x16 && deviceAddress != 0x7f){
                                continue;
                            }
                            if(order != 0x19 && order != 0x17 && order != 0x11){
                                continue;
                            }
                            orderList.add(bytes);
                        }
                    }
                }

                for (byte[] data : orderList) {
                    byte length = data[6];
                    String lengthHex = BytesUtils.byteToHex(length);
                    int lengthInt = BytesUtils.hex16to10(lengthHex);
                    byte[] bytes = BytesUtils.SubByte(data, 0, lengthInt);

                    byte deviceAddress = bytes[4];
                    byte order = bytes[5];

                    if (order == 0x19) {
                    } else if(order == 0x17){
                        Log.d(TAG, "线路站点下载：" + BytesUtils.bytesToHex(bytes));
                        anlzData(null,data);
                    } else if(order == 0x11){
                    }
                }
            }
        }).start();

    }

    int testIndex = 1;
    String testInOutFlag = "00";
    String testUpDownFlag = "00";
    public void next(){
        String indexStr = Integer.toHexString(testIndex);
        String stringBuilder = "24242424" + //包头
                "7f" + //地址
                "11" + //命令
                "11" + //长度
                testUpDownFlag + //方向
                testInOutFlag +//进出站
                "3042313221" +
                ( indexStr.length() == 1 ? ("0" + indexStr) : indexStr) + //站点编号
                "9123";
        d( "next: 命令：" + stringBuilder);
        anlzData(null,BytesUtils.hexToByteArray(stringBuilder));

        //进站
        if(TextUtils.equals("00",testInOutFlag)){
            testInOutFlag = "01";
        } else {
            testInOutFlag = "00";
            testIndex ++; //进站时再累加序号
        }

        //上行
        if(TextUtils.equals("00",testUpDownFlag)){
            if(testIndex >= upSiteMap.size()){
                testIndex = 1;
                testUpDownFlag = "01";
            }
        } else if(TextUtils.equals("01",testUpDownFlag)){
            if(testIndex >= downSiteMap.size()){
                testIndex = 1;
                testUpDownFlag = "00";
            }
        }



//        if(queue.isEmpty()){
//            List<String> stringList = FileIOUtils.readFile2List(new File(Environment.getExternalStorageDirectory(),"TMTM.txt"));
//            if(!stringList.isEmpty()){
//                for (String s : stringList) {
//                    if(TextUtils.isEmpty(s)){
//                        continue;
//                    }
//                    if(s.contains("<-----")){
//                        continue;
//                    }
//                    if(s.contains("<---")){
//                        int i = s.lastIndexOf("-");
//                        String substring = s.substring(i + 1);
//
//                        byte[] bytes = BytesUtils.hexToByteArray(substring);
//                        if(bytes.length < 6 /*|| bytes[6] != 0x11*/){
//                            continue;
//                        }
//
//                        byte deviceAddress = bytes[4];
//                        byte order = bytes[5];
//                        if(deviceAddress != 0x17 && deviceAddress != 0x16 && deviceAddress != 0x7f){
//                            continue;
//                        }
//                        if(/*order != 0x19 && order != 0x17 && */order != 0x11){
//                            continue;
//                        }
//                        String s1 = BytesUtils.bytesToHex(bytes);
//                        Log.e(TAG, "next: " + s1);
//                        queue.offer(bytes);
//                    }
//                }
//            }
//        } else {
//            byte[] poll = queue.poll();
//            Log.d(TAG, "run: " + BytesUtils.bytesToHex(poll));
//            anlzData(null,poll);
//        }

//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//
//                List<String> stringList = FileIOUtils.readFile2List(new File(Environment.getExternalStorageDirectory(),"TMTM.txt"));
//                if(!stringList.isEmpty()){
//                    for (String s : stringList) {
//                        if(TextUtils.isEmpty(s)){
//                            continue;
//                        }
//                        if(s.contains("<-----")){
//                            continue;
//                        }
//                        if(s.contains("<---")){
//                            int i = s.lastIndexOf("-");
//                            String substring = s.substring(i + 1);
//
//                            byte[] bytes = BytesUtils.hexToByteArray(substring);
//                            if(bytes.length < 6 /*|| bytes[6] != 0x11*/){
//                                continue;
//                            }
//
//                            byte deviceAddress = bytes[4];
//                            byte order = bytes[5];
//                            if(deviceAddress != 0x17 && deviceAddress != 0x16 && deviceAddress != 0x7f){
//                                continue;
//                            }
//                            if(/*order != 0x19 && order != 0x17 && */order != 0x11){
//                                continue;
//                            }
//                            queue.offer(bytes);
//                        }
//                    }
//                }
//
////                for (byte[] data : orderList) {
//////                    byte length = data[6];
//////                    String lengthHex = BytesUtils.byteToHex(length);
//////                    int lengthInt = BytesUtils.hex16to10(lengthHex);
//////                    byte[] bytes = BytesUtils.SubByte(data, 0, lengthInt);
//////
//////                    byte deviceAddress = bytes[4];
//////                    byte order = bytes[5];
//////                    if(order != 0x11){
//////                        continue;
//////                    }
//////
//////                    byte UP_DOWN_FLAG = bytes[7];
//////                    byte IN_OUT = bytes[8];//进出站标识
//////                    byte STATION_INDEX = bytes[14];//站点序号
//////
//////                    int stationIndex = BytesUtils.hex16to10(BytesUtils.byteToHex(STATION_INDEX));
//////                    Log.e(TAG, (UP_DOWN_FLAG == 0x00 ? "上行" : "下行") + " --- " + (IN_OUT == 0x00 ? "进站：" : IN_OUT == 0x01 ?  "出站：" : "服务用语") + " --- " + stationIndex);
////
////                    Log.d(TAG, "run: " + BytesUtils.bytesToHex(data));
////                    anlzData(null,data);
////                }
//
////                for (byte[] data : orderList) {
////
////                    byte length = data[6];
////                    String lengthHex = BytesUtils.byteToHex(length);
////                    int lengthInt = BytesUtils.hex16to10(lengthHex);
////                    byte[] bytes = BytesUtils.SubByte(data, 0, lengthInt);
////
////                    byte deviceAddress = bytes[4];
////                    byte order = bytes[5];
////
////                    if (order == 0x19) {
////                    } else if(order == 0x17){
////                    } else if(order == 0x11){
////                        Log.e(TAG, BytesUtils.bytesToHex(data));
////
////                        byte UP_DOWN_FLAG = bytes[7];
////                        byte IN_OUT = bytes[8];//进出站标识
////                        byte STATION_INDEX = bytes[14];//站点序号
////                        int stationIndex = BytesUtils.hex16to10(BytesUtils.byteToHex(STATION_INDEX));
////                        Log.e(TAG, (UP_DOWN_FLAG == 0x00 ? "上行" : "下行") + " --- " + (IN_OUT == 0x00 ? "进站：" : IN_OUT == 0x01 ?  "出站：" : "服务用语") + " --- " + stationIndex);
////
//////                        anlzData(null,data);
////                    }
////
////                }
//            }
//        }).start();
    }

    public void query(){
//        String hex = "2424242417190b0c00cd91";
//        anlzData(null,BytesUtils.hexToByteArray(hex));

        new Thread(new Runnable() {
            @Override
            public void run() {
                List<byte[]> orderList = new ArrayList<>();

                List<String> stringList = FileIOUtils.readFile2List(new File(Environment.getExternalStorageDirectory(),"TMTM.txt"));
                if(!stringList.isEmpty()){
                    for (String s : stringList) {
                        if(TextUtils.isEmpty(s)){
                            continue;
                        }
                        if(s.contains("<-----")){
                            continue;
                        }
                        if(s.contains("<---")){
                            int i = s.lastIndexOf("-");
                            String substring = s.substring(i + 1);

                            byte[] bytes = BytesUtils.hexToByteArray(substring);
                            if(bytes.length < 6 /*|| bytes[6] != 0x11*/){
                                continue;
                            }

                            byte deviceAddress = bytes[4];
                            byte order = bytes[5];
                            if(deviceAddress != 0x17 && deviceAddress != 0x16 && deviceAddress != 0x7f){
                                continue;
                            }
                            if(order != 0x19 && order != 0x17 && order != 0x11){
                                continue;
                            }
                            orderList.add(bytes);
                        }
                    }
                }

                for (byte[] data : orderList) {
                    byte length = data[6];
                    String lengthHex = BytesUtils.byteToHex(length);
                    int lengthInt = BytesUtils.hex16to10(lengthHex);
                    byte[] bytes = BytesUtils.SubByte(data, 0, lengthInt);

                    byte deviceAddress = bytes[4];
                    byte order = bytes[5];

                    if (order == 0x19) {
                        byte PACKAGE_FLAG = bytes[7];
                        String flag = BytesUtils.byteToHex(PACKAGE_FLAG);
                        Log.d(TAG, "线路信息查询：" + flag + " --- " + BytesUtils.bytesToHex(bytes));
                        anlzData(null,data);
                    } else if(order == 0x17){
//                        Log.d(TAG, "线路站点下载：" + BytesUtils.bytesToHex(bytes));
//                        anlzData(null,data);
                    } else if(order == 0x11) {
//                        Log.d(TAG, "进出站播报：" + BytesUtils.bytesToHex(bytes));
                    }
                }
            }
        }).start();
    }

    public void testInfo(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                /*List<byte[]> orderList = new ArrayList<>();

                List<String> stringList = FileIOUtils.readFile2List(new File(Environment.getExternalStorageDirectory(),"TMTM.txt"));
                if(!stringList.isEmpty()){
                    for (String s : stringList) {
                        if(TextUtils.isEmpty(s)){
                            continue;
                        }
                        if(s.contains("<-----")){
                            continue;
                        }
                        if(s.contains("<---")){
                            int i = s.lastIndexOf("-");
                            String substring = s.substring(i + 1);

                            byte[] bytes = BytesUtils.hexToByteArray(substring);
                            if(bytes.length < 6 *//*|| bytes[6] != 0x11*//*){
                                continue;
                            }

                            byte deviceAddress = bytes[4];
                            byte order = bytes[5];
                            if(deviceAddress != 0x17 && deviceAddress != 0x16 && deviceAddress != 0x7f){
                                continue;
                            }
                            if(order != 0x19 && order != 0x17 && order != 0x11){
                                continue;
                            }
                            orderList.add(bytes);
                        }
                    }
                }

                for (byte[] data : orderList) {
                    byte length = data[6];
                    String lengthHex = BytesUtils.byteToHex(length);
                    int lengthInt = BytesUtils.hex16to10(lengthHex);
                    byte[] bytes = BytesUtils.SubByte(data, 0, lengthInt);

                    byte deviceAddress = bytes[4];
                    byte order = bytes[5];

                    if (order == 0x19) {
                        byte PACKAGE_FLAG = bytes[7];
                        String flag = BytesUtils.byteToHex(PACKAGE_FLAG);
                        Log.d(TAG, "线路信息查询：" + flag + " --- " + BytesUtils.bytesToHex(bytes));
                        handle(null,data);
                    } else if(order == 0x17){
//                        Log.d(TAG, "线路站点下载：" + BytesUtils.bytesToHex(bytes));
//                        anlzData(null,data);
                    } else if(order == 0x11) {
//                        Log.d(TAG, "进出站播报：" + BytesUtils.bytesToHex(bytes));
                    }
                }
*/
                String s =
                        "24242424" +
                                "16" +
                                "21" +
                                "10" +
                                "38" +
                                "16071001161c" +
                                "bbcb";
                byte[] bytes = BytesUtils.hexToByteArray(s);
                anlzData(null,bytes);
            }
        }).start();
    }
}
